package org.jsola.hr.service.impl;

import org.jsola.admin.dto.DictItemUpdateDTO;
import org.jsola.admin.entity.DictItemDO;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IProductDAO;
import org.jsola.hr.dto.ProductAddDTO;
import org.jsola.hr.dto.ProductUpdateDTO;
import org.jsola.hr.entity.ProductBannerDO;
import org.jsola.hr.entity.ProductDO;
import org.jsola.hr.query.ProductQuery;
import org.jsola.hr.service.IProductBannerService;
import org.jsola.hr.service.IProductService;
import org.jsola.hr.vo.ProductListVO;
import org.jsola.hr.vo.ProductVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 产品
 *
 * @author zhr
 */
@Service("hrProductServiceImpl")
public class ProductServiceImpl implements IProductService {

    @Autowired
    private IProductDAO productDAO;

    @Autowired
    private IProductBannerService productBannerService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public ProductVO save(ProductAddDTO productAddDTO, TokenUser tokenUser) {
        // 查询租户下所有产品
        List<ProductDO> productDOList = selectBySite(tokenUser.getSiteId());
        ParamException.isFalse(productDOList.parallelStream().anyMatch(productDO
                -> productAddDTO.getProductName().equals(productDO.getProductName())), "产品名称已存在");
        // 转DO
        ProductDO productDO = productAddDTO.to(ProductDO.class);
        // 保存
        productDO = save(productDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return productDO.to(ProductVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(ProductUpdateDTO productUpdateDTO, TokenUser tokenUser) {
        // 查询租户下所有产品
        List<ProductDO> productDOList = selectBySite(tokenUser.getSiteId());
        productDOList = productDOList.parallelStream().filter(productDO
                -> !productUpdateDTO.getId().equals(productDO.getId())).collect(Collectors.toList());
        ParamException.isFalse(productDOList.parallelStream().anyMatch(productDO
                -> productUpdateDTO.getProductName().equals(productDO.getProductName())), "产品名称已存在");
        //转DO
        ProductDO productDO = productUpdateDTO.to(ProductDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(productDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... productIds) {
        // 查询分类的轮播信息 若存在 不允许删除
        List<ProductBannerDO> productBannerDOList = productBannerService.selectDoByProductIds(
                Arrays.asList(productIds), tokenUser.getSiteId());
        ParamException.isTrue(CollectionUtils.isEmpty(productBannerDOList), "产品已设置轮播，无法删除");
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) productIds);
    }


    @Override
    public ProductVO selectById(String productId, String siteId) {
        ProductDO productDO = selectDOById(productId, siteId);
        if (productDO == null) {
            return null;
        }
        return productDO.to(ProductVO.class);
    }

    @Override
    public List<ProductDO> selectDoByIds(List<String> productIds, String siteId) {
        return listByIds(siteId, productIds.parallelStream().toArray(Object[]::new));
    }

    @Override
    public List<ProductDO> selectDoByProductTypeIds(List<String> productTypeIds, String siteId) {
        if (CollectionUtils.isEmpty(productTypeIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(ProductDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId)
                .andIn("productTypeId", productTypeIds);
        return productDAO.selectByExample(example);
    }

    @Override
    public List<ProductListVO> select(ProductQuery productQuery, String siteId) {
        List<ProductDO> productDOList = selectDO(productQuery, siteId);
        if (CollectionUtils.isEmpty(productDOList)) {
            return productDOList == null ? null : new ArrayList<>();
        }
        return productDOList.stream()
                .map(productDO -> productDO.to(ProductListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(ProductQuery productQuery, String siteId) {
        Example example = buildExample(productQuery, siteId);
        return productDAO.selectCountByExample(example);
    }

    @Override
    public Page<ProductListVO> selectPage(ProductQuery productQuery, String siteId) {
        Example example = buildExample(productQuery, siteId);
        Page<ProductDO> page = productDAO.selectPageByExample(example,
                productQuery.getPageNo(),
                productQuery.getPageSize());

        return page.to(ProductListVO.class);
    }

    @Override
    public ProductDO selectDOById(String productId, String siteId) {
        return listById(productId, siteId);
    }

    @Override
    public List<ProductDO> selectDO(ProductQuery productQuery, String siteId) {
        Example example = buildExample(productQuery, siteId);
        return productDAO.selectByExample(example);
    }

    @Override
    public Page<ProductDO> selectByProductTypeIdAndProductName(String productTypeId, String productName
            , Integer pageNo, Integer pageSize, String siteId) {
        Example example = new Example(ProductDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (!StringUtils.isEmpty(productName)) {
            example.and().andLike("productName", "%" + productName + "%");
        }
        if (!"0".equals(productTypeId)) {
            example.and().andEqualTo("productTypeId", productTypeId);
        }
        example.orderBy("isPrincipal").desc().orderBy("gmtCreate").desc();
        return productDAO.selectPageByExample(example, pageNo, pageSize);
    }

    @Override
    public void updateDict(DictItemDO dictItem, DictItemUpdateDTO dictItemUpdateDTO, TokenUser tokenUser) {
        Example example = new Example(ProductDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1224".equals(dictItem.getDictCode())) {
            example.and().andCondition("FIND_IN_SET('" + dictItem.getDictItemValue() + "' , product_tag)");
        } else {
            return;
        }
        List<ProductDO> productDOList = productDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(productDOList)) {
            return;
        }
        // 替换内容
        for (ProductDO productDO : productDOList) {
            String productTag = productDO.getProductTag();
            String[] split = productTag.split(",");
            List<String> newProductTagList = new ArrayList<>();
            for (String oneTag : split) {
                if (oneTag.equals(dictItem.getDictItemValue())) {
                    newProductTagList.add(dictItemUpdateDTO.getDictItemValue());
                } else {
                    newProductTagList.add(oneTag);
                }
            }
            productDO.setProductTag(String.join(",", newProductTagList));
            updateByIdSelective(productDO, tokenUser.getSiteId(), tokenUser.getUserId());
        }
    }

    @Override
    public Integer selectDict(DictItemDO dictItem, TokenUser tokenUser) {
        Example example = new Example(ProductDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1224".equals(dictItem.getDictCode())) {
            example.and().andCondition("FIND_IN_SET('" + dictItem.getDictItemValue() + "' , product_tag)");
        } else {
            return 0;
        }
        return productDAO.selectCountByExample(example);
    }


    @Override
    public List<ProductDO> selectBySite(String siteId) {
        Example example = new Example(ProductDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        return productDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example
     *
     * @param productQuery 查询参数
     * @param siteId       所属站点id
     * @return example
     */
    private Example buildExample(ProductQuery productQuery, String siteId) {
        Example example = new Example(ProductDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (productQuery.getIsPrincipal() != null) {
            example.and().andEqualTo("isPrincipal", productQuery.getIsPrincipal());
        }
        // 排序
        ExampleKit.setExampleOrder(example, productQuery.getOrders());
        return example;
    }
}




